home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 008 / src / hack.makemon.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  4KB  |  157 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* hack.makemon.c version 1.0.1 - newly created demons do not sleep */
  3.  
  4. #include    "hack.h"
  5. extern char fut_geno[];
  6.  
  7. extern char *index();
  8.  
  9. struct monst zeromonst;
  10.  
  11. /*
  12.  * called with [x,y] = coordinates;
  13.  *    [0,0] means anyplace
  14.  *    [u.ux,u.uy] means: call mnexto (not in MKLEV)
  15.  *
  16.  *    In case we make an Orc or killer bee, we make an entire horde (swarm);
  17.  *    note that in this case we return only one of them (the one at [x,y]).
  18.  */
  19. struct monst *
  20. makemon(ptr,x,y)
  21. register struct permonst *ptr;
  22. {
  23.     register struct monst *mtmp;
  24.     register int tmp, ct;
  25.     boolean anything = (!ptr);
  26.  
  27.     if(x != 0 || y != 0) if(m_at(x,y)) return((struct monst *) 0);
  28.     if(ptr){
  29.         if(index(fut_geno, ptr->mlet)) return((struct monst *) 0);
  30.     } else {
  31.         ct = CMNUM - strlen(fut_geno);
  32.         if(index(fut_geno, 'm')) ct++;  /* make only 1 minotaur */
  33.         if(index(fut_geno, '@')) ct++;
  34.         if(ct <= 0) return(0);           /* no more monsters! */
  35.         tmp = rn2(ct*dlevel/24 + 7);
  36.         if(tmp < dlevel - 4) tmp = rn2(ct*dlevel/24 + 12);
  37.         if(tmp >= ct) tmp = rn1(ct - ct/2, ct/2);
  38.         for(ct = 0; ct < CMNUM; ct++){
  39.             ptr = &mons[ct];
  40.             if(index(fut_geno, ptr->mlet))
  41.                 continue;
  42.             if(!tmp--) goto gotmon;
  43.         }
  44.         panic("makemon?");
  45.     }
  46. gotmon:
  47.     mtmp = newmonst(ptr->pxlth);
  48.     *mtmp = zeromonst;    /* clear all entries in structure */
  49.     for(ct = 0; ct < ptr->pxlth; ct++)
  50.         ((char *) &(mtmp->mextra[0]))[ct] = 0;
  51.     mtmp->nmon = fmon;
  52.     fmon = mtmp;
  53.     mtmp->m_id = flags.ident++;
  54.     mtmp->data = ptr;
  55.     mtmp->mxlth = ptr->pxlth;
  56.     if(ptr->mlet == 'D') mtmp->orig_hp = mtmp->mhp = 80;
  57.     else if(!ptr->mlevel) mtmp->orig_hp = mtmp->mhp = rnd(4);
  58.     else mtmp->orig_hp = mtmp->mhp = d(ptr->mlevel, 8);
  59.     mtmp->mx = x;
  60.     mtmp->my = y;
  61.     mtmp->mcansee = 1;
  62.     if(ptr->mlet == 'M')
  63.         mtmp->mimic = ']';
  64. /*        if (!ismklev)
  65.            { */
  66.        if(x == u.ux && y == u.uy)
  67.         mnexto(mtmp);
  68.        if(x == 0 && y == 0)
  69.         rloc(mtmp);
  70. /*           }*/
  71.     if(ptr->mlet == 's' || ptr->mlet == 'S') {
  72.         mtmp->mhide = mtmp->mundetected = 1;
  73.         if(ismklev && mtmp->mx && mtmp->my)
  74.             mkobj_at(0, mtmp->mx, mtmp->my);
  75.     }
  76.     if(ptr->mlet == ':') {
  77.         mtmp->cham = 1;
  78.                 if (ismklev)
  79.            (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
  80.     }
  81.     if(ptr->mlet == 'I') mtmp->minvis = 1;
  82.     if(ptr->mlet == 'L' || ptr->mlet == 'N'
  83.         ||(ismklev && ptr->mlet != '&' && ptr->mlet != 'w' && rn2(5))
  84.     ) mtmp->msleep = 1;
  85.  
  86. #ifndef NOWORM
  87. /*        if (!ismklev) */
  88.        if(ptr->mlet == 'w' && getwn(mtmp))
  89.         initworm(mtmp);
  90. #endif NOWORM
  91.  
  92.     if(anything) if(ptr->mlet == 'O' || ptr->mlet == 'k') {
  93.         coord enexto();
  94.         coord mm;
  95.         register int cnt = rnd(10);
  96.         mm.x = x;
  97.         mm.y = y;
  98.         while(cnt--) {
  99.             mm = enexto(mm.x, mm.y);
  100.             (void) makemon(ptr, mm.x, mm.y);
  101.         }
  102.     }
  103.  
  104.     return(mtmp);
  105. }
  106.  
  107. coord
  108. enexto(xx,yy)
  109. register xchar xx,yy;
  110. {
  111.     register xchar x,y;
  112.     coord foo[15], *tfoo;
  113.     int range;
  114.  
  115.     tfoo = foo;
  116.     range = 1;
  117.     do {    /* full kludge action. */
  118.         for(x = xx-range; x <= xx+range; x++)
  119.             if(goodpos(x, yy-range)) {
  120.                 tfoo->x = x;
  121.                 (tfoo++)->y = yy-range;
  122.                 if(tfoo == &foo[15]) goto foofull;
  123.             }
  124.         for(x = xx-range; x <= xx+range; x++)
  125.             if(goodpos(x,yy+range)) {
  126.                 tfoo->x = x;
  127.                 (tfoo++)->y = yy+range;
  128.                 if(tfoo == &foo[15]) goto foofull;
  129.             }
  130.         for(y = yy+1-range; y < yy+range; y++)
  131.             if(goodpos(xx-range,y)) {
  132.                 tfoo->x = xx-range;
  133.                 (tfoo++)->y = y;
  134.                 if(tfoo == &foo[15]) goto foofull;
  135.             }
  136.         for(y = yy+1-range; y < yy+range; y++)
  137.             if(goodpos(xx+range,y)) {
  138.                 tfoo->x = xx+range;
  139.                 (tfoo++)->y = y;
  140.                 if(tfoo == &foo[15]) goto foofull;
  141.             }
  142.         range++;
  143.     } while(tfoo == foo);
  144. foofull:
  145.     return( foo[rn2(tfoo-foo)] );
  146. }
  147.  
  148. goodpos(x,y)    /* used only in mnexto and rloc */
  149. {
  150.     return(
  151.     ! (x < 1 || x > COLNO-2 || y < 1 || y > ROWNO-2 ||
  152.        m_at(x,y) || levl[x][y].typ < DOOR
  153.        || (ismklev && x == u.ux && y == u.uy)
  154.        || (ismklev && sobj_at(ENORMOUS_ROCK, x, y))
  155.     ));
  156. }
  157.